<!DOCTYPE html>
<html>
<meta charset="utf-8">
<head>
    <style type="text/css">
    /* STYLE_GLOBAL_PLACE_HOLDER */
    </style>

    <style type="text/css">
    @keyframes flash { 
  0% { color: rgb(128, 203, 196); }
  10% { color: rgb(0, 137, 123); }
  40% { color: rgb(0, 137, 123); }
  50% { color: rgb(128, 203, 196); }
  60% { color: rgb(0, 137, 123); }
  90% { color: rgb(0, 137, 123); }
}
.highlighted-anchor { animation: flash 1s; }
body { margin: 0px auto; font-family: Helvetica, sans-serif, Tahoma, Arial, Verdana, Geneva, Georgia, Palatino, "Times New Roman", "Hiragino Sans GB", 冬青黑体, "Microsoft YaHei", 微软雅黑, "Microsoft YaHei UI", "WenQuanYi Micro Hei", 文泉驿雅黑, Dengxian, 等线体, STXihei, 华文细黑, "Liberation Sans", "Droid Sans", NSimSun, 新宋体, SimSun, 宋体; color: rgb(34, 34, 34); line-height: 1.5; padding: 15px; background: rgb(245, 245, 245); font-size: 16px; }
h1, h2, h3, h4, h5, h6 { color: rgb(34, 34, 34); font-weight: bold; margin-top: 20px; margin-bottom: 10px; padding: 0px; }
p { padding: 0px; margin-top: 16px; margin-bottom: 16px; }
h1 { font-size: 30px; }
h2 { font-size: 26px; }
h3 { font-size: 24px; }
h4 { font-size: 22px; }
h5 { font-size: 20px; }
h6 { font-size: 18px; }
a { color: rgb(0, 153, 255); margin: 0px; padding: 0px; vertical-align: baseline; text-decoration: none; word-break: break-all; }
a:hover { text-decoration: underline; color: rgb(255, 102, 0); }
a:visited { color: purple; }
ul, ol { padding: 0px 0px 0px 24px; }
li { line-height: 24px; }
li ul, li ol { margin-left: 16px; }
p, ul, ol { font-size: 16px; line-height: 24px; }
pre { display: block; overflow-y: hidden; overflow-x: auto; }
code { font-family: Consolas, Monaco, monospace, Courier; font-size: 16px; color: rgb(142, 36, 170); word-break: break-all; }
pre code { display: block; overflow-x: auto; padding: 0.5em; color: rgb(34, 34, 34); background-color: rgb(224, 224, 224); line-height: 1.5; font-family: Consolas, Monaco, monospace, Courier; white-space: pre; }
pre code.markdown-metadata { border-left: 5px solid rgb(0, 137, 123); }
aside { display: block; float: right; width: 390px; }
blockquote { color: rgb(102, 102, 102); border-left: 0.5em solid rgb(122, 122, 122); padding: 0px 2em; margin-left: 0px; }
blockquote p { color: rgb(102, 102, 102); }
hr { display: block; text-align: left; margin: 1em 0px; border: none; height: 2px; background: rgb(153, 153, 153); }
table { padding: 0px; border-collapse: collapse; }
table tr { border-top: 1px solid rgb(204, 204, 204); background-color: white; margin: 0px; padding: 0px; }
table tr:nth-child(2n) { background-color: rgb(248, 248, 248); }
table tr th { font-weight: bold; border: 1px solid rgb(204, 204, 204); margin: 0px; padding: 6px 13px; }
table tr td { border: 1px solid rgb(204, 204, 204); margin: 0px; padding: 6px 13px; }
table tr th :first-child, table tr td :first-child { margin-top: 0px; }
table tr th :last-child, table tr td :last-child { margin-bottom: 0px; }
div.mermaid-diagram { margin: 16px 0px; overflow-y: hidden; }
div.flowchart-diagram { padding: 0px 5px; margin: 16px 0px; width: fit-content; overflow: hidden; }
div.plantuml-diagram { padding: 5px 5px 0px; margin: 16px 0px; width: fit-content; overflow: hidden; }
.img-package { text-align: center; }
img.img-center { display: block; margin-left: auto; margin-right: auto; }
div.img-caption { min-width: 20%; max-width: 80%; display: inline-block; padding: 10px; margin: 0px auto; border-bottom: 1px solid rgb(192, 192, 192); color: rgb(108, 108, 108); text-align: center; line-height: 1.5; }
table.hljs-ln tr { border: none; background-color: transparent; }
table.hljs-ln tr td { border: none; background-color: transparent; }
table.hljs-ln tr td.hljs-ln-numbers { user-select: none; text-align: center; color: rgb(170, 170, 170); border-right: 1px solid rgb(204, 204, 204); vertical-align: top; padding-right: 5px; white-space: nowrap; }
table.hljs-ln tr td.hljs-ln-code { padding-left: 10px; }
::-webkit-scrollbar { background-color: rgb(234, 234, 234); width: 14px; height: 14px; border: none; }
::-webkit-scrollbar-corner { background-color: rgb(234, 234, 234); }
::-webkit-scrollbar-button { height: 14px; width: 14px; background-color: rgb(234, 234, 234); }
::-webkit-scrollbar-button:hover { background-color: rgb(208, 208, 208); }
::-webkit-scrollbar-button:active { background-color: rgb(178, 178, 178); }
::-webkit-scrollbar-track { background-color: rgb(234, 234, 234); }
::-webkit-scrollbar-thumb { border: none; background-color: rgb(218, 218, 218); }
::-webkit-scrollbar-thumb:hover { background-color: rgb(208, 208, 208); }
::-webkit-scrollbar-thumb:active { background-color: rgb(178, 178, 178); }
::-webkit-scrollbar-button:horizontal:increment { background-image: url('data:image/svg+xml;utf8,<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <g>  <title>Layer 1</title>  <g transform="rotate(-90 256.00000000000006,256) " id="svg_1">   <polygon fill="#333333" id="svg_2" points="128,192 256,320 384,192  "/>  </g> </g></svg>'); background-repeat: no-repeat; background-size: contain; }
::-webkit-scrollbar-button:horizontal:decrement { background-image: url('data:image/svg+xml;utf8,<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <g>  <title>Layer 1</title>  <g transform="rotate(90 255.99999999999997,256.00000000000006) " id="svg_1">   <polygon points="128,192 256,320 384,192  " id="svg_2" fill="#333333"/>  </g> </g></svg>'); background-repeat: no-repeat; background-size: contain; }
::-webkit-scrollbar-button:vertical:increment { background-image: url('data:image/svg+xml;utf8,<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <g>  <title>Layer 1</title>  <g transform="null" id="svg_1">   <polygon points="128,192 256,320 384,192  " id="svg_2" fill="#333333"/>  </g> </g></svg>'); background-repeat: no-repeat; background-size: contain; }
::-webkit-scrollbar-button:vertical:decrement { background-image: url('data:image/svg+xml;utf8,<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg"> <g>  <title>Layer 1</title>  <g transform="rotate(180 255.99999999999997,256) " id="svg_1">   <polygon points="128,192 256,320 384,192  " id="svg_2" fill="#333333"/>  </g> </g></svg>'); background-repeat: no-repeat; background-size: contain; }
::selection { background: rgb(25, 118, 210); color: rgb(245, 245, 245); }
.hljs { display: block; overflow-x: auto; padding: 0.5em; background: rgb(224, 224, 224); }
.hljs, .hljs-subst { color: rgb(54, 54, 54); }
.hljs-comment { color: rgb(118, 118, 118); }
.hljs-keyword, .hljs-attribute, .hljs-selector-tag, .hljs-meta-keyword, .hljs-doctag, .hljs-name { color: rgb(0, 0, 238); }
.hljs-type, .hljs-string, .hljs-number, .hljs-selector-id, .hljs-selector-class, .hljs-quote, .hljs-template-tag, .hljs-deletion { color: rgb(136, 0, 0); }
.hljs-title, .hljs-section { color: rgb(136, 0, 0); font-weight: bold; }
.hljs-regexp, .hljs-symbol, .hljs-variable, .hljs-template-variable, .hljs-link, .hljs-selector-attr, .hljs-selector-pseudo { color: rgb(188, 96, 96); }
.hljs-literal { color: rgb(175, 0, 215); }
.hljs-built_in, .hljs-bullet, .hljs-code, .hljs-addition { color: rgb(0, 135, 0); }
.hljs-meta { color: rgb(31, 113, 153); }
.hljs-meta-string { color: rgb(77, 153, 191); }
.hljs-emphasis { font-style: italic; }
.hljs-strong { font-weight: bold; }

    </style>

    <!-- EXTRA_PLACE_HOLDER -->

<!-- HEAD_PLACE_HOLDER -->
</head>
<body>
<h1>T100推流盒子开发文档</h1>
<div class="vnote-toc"><ul><li><a href="#toc_0">1. 简介</a><ul><li><a href="#toc_1">1.1. 功能定位</a></li><li><a href="#toc_2">1.2. 整体架构</a></li><li><a href="#toc_3">1.3. 功能清单</a><ul><li><a href="#toc_4">1.3.1. 主要功能</a></li><li><a href="#toc_5">1.3.2. 二次开发</a></li></ul></li></ul></li><li><a href="#toc_6">2. 编译</a><ul><li><a href="#toc_7">2.1. 编译要求</a></li><li><a href="#toc_8">2.2. Windows</a></li><li><a href="#toc_9">2.3. Linux</a></li></ul></li><li><a href="#toc_10">3. 运行</a><ul><li><a href="#toc_11">3.1. 配置</a></li><li><a href="#toc_12">3.2. 启动程序</a></li><li><a href="#toc_13">3.3. 守护进程</a><ul><li><a href="#toc_14">3.3.1. 工作原理</a></li><li><a href="#toc_15">3.3.2. 监控应用</a></li><li><a href="#toc_16">3.3.3. 开机自启</a></li></ul></li></ul></li><li><a href="#toc_17">4. 交互协议</a><ul><li><a href="#toc_18">4.1. 设计原则</a></li><li><a href="#toc_19">4.2. 交互格式</a><ul><li><a href="#toc_20">4.2.1. 响应结果格式</a></li><li><a href="#toc_21">4.2.2. 错误码</a></li><li><a href="#toc_22">4.2.3. 参数类型</a></li></ul></li><li><a href="#toc_23">4.3. 访问API</a><ul><li><a href="#toc_24">4.3.1. 启用</a></li><li><a href="#toc_25">4.3.2. 使用</a></li></ul></li><li><a href="#toc_26">4.4. HTTP回调</a></li><li><a href="#toc_27">4.5. 约定术语</a><ul><li><a href="#toc_28">4.5.1. 服务标识</a></li><li><a href="#toc_29">4.5.2. 流标识</a></li></ul></li></ul></li><li><a href="#toc_30">5. API</a><ul><li><a href="#toc_31">5.1. 基本信息</a><ul><li><a href="#toc_32">5.1.1. 获取服务标识</a></li><li><a href="#toc_33">5.1.2. 获取版本信息</a></li><li><a href="#toc_34">5.1.3. 获取设备简要信息[开发中]</a></li><li><a href="#toc_35">5.1.4. 获取服务进程信息[开发中]</a></li><li><a href="#toc_36">5.1.5. 获取服务内存信息[开发中]</a></li><li><a href="#toc_37">5.1.6. 获取设备硬盘信息[开发中]</a></li></ul></li><li><a href="#toc_38">5.2. 通道配置</a><ul><li><a href="#toc_39">5.2.1. 设置通道</a></li><li><a href="#toc_40">5.2.2. 设置通道是否可用</a></li><li><a href="#toc_41">5.2.3. 设置通道是否按需[开发中]</a></li><li><a href="#toc_42">5.2.4. 获取通道信息</a></li><li><a href="#toc_43">5.2.5. 获取在用通道</a></li><li><a href="#toc_44">5.2.6. 获取所有通道</a></li><li><a href="#toc_45">5.2.7. 开始播放某个通道</a></li><li><a href="#toc_46">5.2.8. 停止播放某个通道</a></li></ul></li><li><a href="#toc_47">5.3. 推流操作</a><ul><li><a href="#toc_48">5.3.1. 设置推流地址</a></li><li><a href="#toc_49">5.3.2. 推某通道流</a></li><li><a href="#toc_50">5.3.3. 停止某路推流</a></li><li><a href="#toc_51">5.3.4. 设置推流通道[测试中]</a></li><li><a href="#toc_52">5.3.5. 获取推流器信息</a></li><li><a href="#toc_53">5.3.6. 获取在用推流器</a></li><li><a href="#toc_54">5.3.7. 获取推流器状态</a></li></ul></li><li><a href="#toc_55">5.4. 流信息操作</a><ul><li><a href="#toc_56">5.4.1. 获取虚拟主机</a></li><li><a href="#toc_57">5.4.2. 获取所有流</a></li><li><a href="#toc_58">5.4.3. 获取码流地址</a></li><li><a href="#toc_59">5.4.4. 获取流状态</a></li></ul></li><li><a href="#toc_60">5.5. 截图</a><ul><li><a href="#toc_61">5.5.1. 获取封面截图</a></li></ul></li><li><a href="#toc_62">5.6. 功能启停</a><ul><li><a href="#toc_63">5.6.1. 设置功能码</a></li><li><a href="#toc_64">5.6.2. 设备功能启停</a></li><li><a href="#toc_65">5.6.3. 查看功能状态</a></li></ul></li><li><a href="#toc_66">5.7. 平台接入</a><ul><li><a href="#toc_67">5.7.1. 设置心跳</a></li></ul></li><li><a href="#toc_68">5.8. 回调操作</a><ul><li><a href="#toc_69">5.8.1. 设置回调</a></li><li><a href="#toc_70">5.8.2. 新增回调</a></li><li><a href="#toc_71">5.8.3. 获取回调</a></li><li><a href="#toc_72">5.8.4. 获取所有回调</a></li><li><a href="#toc_73">5.8.5. 重载回调</a></li><li><a href="#toc_74">5.8.6. 回调详情</a><ul><li><a href="#toc_75">5.8.6.1. on_register - 设备注册</a></li><li><a href="#toc_76">5.8.6.2. on_keep_alive - 设备接入心跳</a></li><li><a href="#toc_77">5.8.6.3. on_play - 成功播放</a></li><li><a href="#toc_78">5.8.6.4. on_teardown - 停止播放</a></li><li><a href="#toc_79">5.8.6.5. on_push - 推流成功</a></li><li><a href="#toc_80">5.8.6.6. on_unpush - 停止推流</a></li><li><a href="#toc_81">5.8.6.7. on_push_auth - 推流认证</a></li><li><a href="#toc_82">5.8.6.8. on_capture - 抓图成功</a></li></ul></li></ul></li><li><a href="#toc_83">5.9. 服务配置</a><ul><li><a href="#toc_84">5.9.1. 写入配置</a></li><li><a href="#toc_85">5.9.2. 获取配置</a></li><li><a href="#toc_86">5.9.3. 配置权限表[开发中]</a></li></ul></li><li><a href="#toc_87">5.10. 系统配置</a><ul><li><a href="#toc_88">5.10.1. 关机</a></li><li><a href="#toc_89">5.10.2. 重启</a></li><li><a href="#toc_90">5.10.3. 网络配置</a><ul><li><a href="#toc_91">5.10.3.1. 获取网卡</a></li><li><a href="#toc_92">5.10.3.2. 设置静态IP</a></li><li><a href="#toc_93">5.10.3.3. 设置DHCP</a></li></ul></li><li><a href="#toc_94">5.10.4. 时间核对[开发中]</a></li></ul></li><li><a href="#toc_95">5.11. 其它</a><ul><li><a href="#toc_96">5.11.1. 推流完整过程</a></li></ul></li></ul></li><li><a href="#toc_97">6. 附录</a><ul><li><a href="#toc_98">6.1. 状态码定义</a><ul><li><a href="#toc_99">6.1.1. HTTP状态码</a></li><li><a href="#toc_100">6.1.2. API状态码[开发中]</a><ul><li><a href="#toc_101">6.1.2.1. 功能码</a></li><li><a href="#toc_102">6.1.2.2. 值操作</a></li><li><a href="#toc_103">6.1.2.3. 协议类型</a></li></ul></li></ul></li><li><a href="#toc_104">6.2. 序列号编码</a></li><li><a href="#toc_105">6.3. 文档日志</a></li></ul></li></ul></div>
<h1 id="toc_0"><a name="toc_0" class="vnote-anchor" href="#"></a>1. 简介</h1>
<h2 id="toc_1"><a name="toc_1" class="vnote-anchor" href="#"></a>1.1. 功能定位</h2>
<p>一款轻量级的安防设备直播推流产品。旨在采集具有标准RTSP/RTMP协议输出的设备音视频源，将这些音视频源数据进行转换、输出。第一是实现在局域网内通过RTSP/RTMP低延时播放，第二是通过HLS/FLV协议实现H5、Android、iOS等多种终端预览，第三是实现将音视频源数据推送到第三方流媒体服务器或者CDN网络，达到安防设备快速互联网级别的直播。</p>
<h2 id="toc_2"><a name="toc_2" class="vnote-anchor" href="#"></a>1.2. 整体架构</h2>
<p><img src='' alt="avatar" width="800"></p>
<h2 id="toc_3"><a name="toc_3" class="vnote-anchor" href="#"></a>1.3. 功能清单</h2>
<h3 id="toc_4"><a name="toc_4" class="vnote-anchor" href="#"></a>1.3.1. 主要功能</h3>
<ul>
<li>支持通过RTSP/RTMP协议接入摄像机</li>
<li>支持RTSP/RTMP/HLS/FLV协议播放</li>
<li>支持PC/Android/iOS/微信/H5等终端在线预览</li>
<li>支持推流到CDN指定RTMP地址</li>
<li>支持录像点播、录像计划、时间录像检索播放[开发中]</li>
<li>支持定时封面截图</li>
<li>支持HTTP接口二次开发</li>
<li>支持用户管理，权限验证[开发中]</li>
<li>支持网页配置管理</li>
</ul>
<h3 id="toc_5"><a name="toc_5" class="vnote-anchor" href="#"></a>1.3.2. 二次开发</h3>
<ul>
<li>
<p>RTSP</p>
<ul>
<li>RTSP 服务器，支持RTMP/MP4转RTSP。</li>
<li>RTSPS 服务器，支持亚马逊echo show这样的设备</li>
<li>RTSP 播放器，支持RTSP代理，支持生成静音音频</li>
<li>RTSP 推流客户端与服务器</li>
<li>支持RTP over UDP/RTP over TCP/RTP over HTTP/RTP组播四种RTP传输方式 。</li>
<li>服务器/客户端完整支持Basic/Digest方式的登录鉴权，全异步可配置化的鉴权接口。</li>
<li>支持H265编码</li>
<li>服务器支持RTSP推流(包括RTP over UDP/RTP over TCP方式)</li>
<li>支持任意编码格式的rtsp推流，只是除H264/H265+AAC外无法转协议</li>
</ul>
</li>
<li>
<p>RTMP</p>
<ul>
<li>RTMP 播放服务器，支持RTSP/MP4转RTMP。</li>
<li>RTMP 发布服务器，支持录制发布流。</li>
<li>RTMP 播放器，支持RTMP代理，支持生成静音音频</li>
<li>RTMP 推流客户端。</li>
<li>支持http-flv直播。</li>
<li>支持https-flv直播。</li>
<li>支持任意编码格式的rtmp推流，只是除H264/H265+AAC外无法转协议</li>
</ul>
</li>
<li>
<p>HLS</p>
<ul>
<li>支持HLS文件生成，自带HTTP文件服务器。</li>
</ul>
</li>
<li>
<p>HTTP[S]</p>
<ul>
<li>服务器支持目录索引生成,文件下载,表单提交请求。</li>
<li>客户端提供文件下载器(支持断点续传),接口请求器,文件上传器。</li>
<li>完整HTTP API服务器，可以作为web后台开发框架。</li>
<li>支持跨域访问。</li>
<li>客户端支持cookie</li>
<li>支持WebSocket服务器</li>
</ul>
</li>
<li>
<p>API</p>
<ul>
<li>支持HTTP Callbacks</li>
<li>支持配置读写</li>
<li>支持通道配置</li>
<li>支持推流器配置</li>
<li>支持流信息统计</li>
<li>支持封面截图</li>
<li>支持其它平台接入</li>
</ul>
</li>
<li>
<p>其他</p>
<ul>
<li>支持输入YUV+PCM自动生成RTSP/RTMP/HLS/MP4.</li>
<li>支持简单的telnet调试。</li>
<li>支持H264的解析，支持B帧的POC计算排序。</li>
<li>支持配置文件热加载</li>
<li>支持流量统计、推流播放鉴权等事件</li>
<li>支持rtsp/rtmp/http虚拟主机</li>
<li>支持flv、mp4文件录制</li>
<li>支持rtps/rtmp点播，支持seek</li>
</ul>
</li>
</ul>
<h1 id="toc_6"><a name="toc_6" class="vnote-anchor" href="#"></a>2. 编译</h1>
<h2 id="toc_7"><a name="toc_7" class="vnote-anchor" href="#"></a>2.1. 编译要求</h2>
<ul>
<li>编译器支持C++11，GCC4.8/Clang3.3/VC2015或以上</li>
<li>cmake3.8.2或以上</li>
<li>OpenSSL [可选]</li>
<li>FFmpeg 4.x.x[可选]</li>
<li>faac 1.2.8[可选]</li>
<li>mp4v2 [可选]</li>
</ul>
<h2 id="toc_8"><a name="toc_8" class="vnote-anchor" href="#"></a>2.2. Windows</h2>
<blockquote>
<p>编译环境</p>
</blockquote>
<ul>
<li>Win10</li>
<li>vs2015</li>
<li>cmake 3.8.2</li>
</ul>
<blockquote>
<p>安装依赖包</p>
</blockquote>
<ul>
<li>安装OpenSSL</li>
<li>安装FFmpeg</li>
</ul>
<blockquote>
<p>源码编译</p>
</blockquote>
<ul>
<li>使用命令行编译:</li>
</ul>
<pre><code class="hljs">git clone --recursive ssh://droid.chow@192.168.0.13:29418/livelib.git
mkdir nvr_build
cd nvr_build
cmake ../livelib -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Debug
</code></pre>
<ul>
<li>使用IDE编译：</li>
</ul>
<pre><code class="hljs">使用CMake-gui生成vs工程文件，打开livelib.sln编译所有工程
</code></pre>
<h2 id="toc_9"><a name="toc_9" class="vnote-anchor" href="#"></a>2.3. Linux</h2>
<blockquote>
<p>编译环境</p>
</blockquote>
<ul>
<li>CentOS 6.5</li>
<li>GCC 4.9.1</li>
<li>cmake 3.8.2</li>
</ul>
<blockquote>
<p>安装依赖包</p>
</blockquote>
<ul>
<li>安装OpenSSL</li>
<li>编译FFmpeg</li>
</ul>
<blockquote>
<p>源码编译</p>
</blockquote>
<pre><code class="hljs">git clone --recursive ssh://droid.chow@192.168.0.13:29418/livelib.git
mkdir nvr_build
cd nvr_build
cmake ../livelib
</code></pre>
<h1 id="toc_10"><a name="toc_10" class="vnote-anchor" href="#"></a>3. 运行</h1>
<h2 id="toc_11"><a name="toc_11" class="vnote-anchor" href="#"></a>3.1. 配置</h2>
<p>进入编译输出目录或者程序解压目录{install}/bin/，打开nvr.ini文件进行配置操作。</p>
<pre><code class="hljs">[broadcast]
; 流量汇报事件流量阈值,单位KB，默认1MB
flowThreshold=1024

[hls]
; HLS文件写缓存大小
fileBufSize=65536
; 录制文件路径
filePath=D:/soft/live/d/bin/httpRoot
; HLS切片时长,单位秒
segDur=6
; HLS切片个数
segNum=3

[http]
; http 字符编码
charSet=gb2312
; http keep-alive秒数
keepAliveSecond=10
; http keep-alive最大请求数
maxReqCount=100
; http 最大请求字节数
maxReqSize=4096
; http 404错误提示内容
notFound=&lt;html&gt;&lt;head&gt;&lt;title&gt;404 Not Found&lt;/title&gt;&lt;/head&gt;&lt;body bgcolor="white"&gt;&lt;center&gt;&lt;h1&gt;您访问的资源不存在！&lt;/h1&gt;&lt;/center&gt;&lt;hr&gt;&lt;center&gt;RAM Stream Server-1.0&lt;/center&gt;&lt;/body&gt;&lt;/html&gt;
; http 端口号
port=80
; http 服务器根目录
rootPath=D:/soft/live/d/bin/httpRoot
; http 文件发送缓存大小
sendBufSize=65536
; https 端口
sslport=1443
; http api端口
api_port=18080

[multicast]
; 组播分配截止地址
addrMax=239.255.255.255
; 组播分配起始地址
addrMin=239.0.0.0
; 组播TTL
udpTTL=64

[record]
; 查看录像的应用名称
appName=record
; 录制文件路径
filePath=D:/soft/live/d/bin/httpRoot
; MP4文件录制大小,默认一个小时
fileSecond=3600
; 每次流化MP4文件的时长,单位毫秒
sampleMS=100

[rtmp]
; RTMP数据包时戳修正，0 - 不启用 1 - 启用
modifyStamp=1
; RTMP端口号
port=1935

[rtp]
; RTP打包最大MTU,公网情况下更小
audioMtuSize=600
; 如果RTP序列正确次数累计达到该数字就启动清空排序缓存
clearCount=10
; 最大RTP时间为13个小时，每13小时回环一次，单位毫秒
cycleMS=46800000
; RTP排序缓存最大个数
maxRtpCount=50
; RTP打包最大MTU,公网情况下更小
videoMtuSize=1400

[rtsp]
; 是否优先base64方式认证？默认Md5方式认证
authBasic=0
; RTSP请求端口号
port=554
; RTSPS请求端口号
sslport=322

; 服务器配置
[server]
; 嵌入式数据文件存放地址
db=/bin/nvr.db
; 服务器ip地址
host=192.168.31.240
; 是否定时发送心跳
keep_alive=true
; 保持心跳间隔时间，单位秒，默认1分钟=60s
keep_timeout=60

[shell]
; 最大请求个数
maxReqSize=1024
; shell端口号
port=9000

[cover]
; 查看截图的应用名称
appName=cover
; 截图文件路径
filePath=D:/soft/live/d/bin/httpRoot
</code></pre>
<h2 id="toc_12"><a name="toc_12" class="vnote-anchor" href="#"></a>3.2. 启动程序</h2>
<p>进入编译输出目录或者程序解压目录{install}/bin/，提供以下几种启动操作：</p>
<ul>
<li>调试模式</li>
</ul>
<pre><code class="hljs">以控制台模式启动，日志信息直接输出在控制台，关闭控制台后程序退出，适用于调试阶段
./nvr
</code></pre>
<ul>
<li>测试模式</li>
</ul>
<pre><code class="hljs">以后台模式启动，关闭控制台后程序不退出，直到程序崩溃或者手工退出，适用于测试阶段
./nvr.sh
</code></pre>
<ul>
<li>发布模式</li>
</ul>
<pre><code class="hljs">以后守护进程模式启动，关闭控制台后程序不退出，程序崩溃程序自动重启，适用于发布运行阶段
./nvrd.sh
</code></pre>
<h2 id="toc_13"><a name="toc_13" class="vnote-anchor" href="#"></a>3.3. 守护进程</h2>
<p>守护进程（daemon）是一直运行的服务端程序。通常在系统后台运行，没有控制终端，不与前台交互。守护进程是长时间运行的进程，一般作为系统服务使用，通常在系统启动后就运行，在系统关闭时才结束。是因为它没有控制终端，无法直接使用控制台和用户交互，一般等待客户端程序与它通信。</p>
<p>应用"softdog"是一个守护进程程序，它是非侵入式的守护进程，从外部监控其它应用程序的运行状态，在应用程序运行异常时时对应用程序进行启动、重启或停止。</p>
<h3 id="toc_14"><a name="toc_14" class="vnote-anchor" href="#"></a>3.3.1. 工作原理</h3>
<p><img src='' alt="avatar" width="800"></p>
<h3 id="toc_15"><a name="toc_15" class="vnote-anchor" href="#"></a>3.3.2. 监控应用</h3>
<p>发布模式使用"softdog"来监控应用程序是否存活，需要配置需要监控的应用。进入编译输出目录或者程序解压目录{install}/bin/，打开damon文件进行配置操作。</p>
<pre><code class="hljs">// nvr daemon configuration file.

// 软件名称
name = "softdog"

// 监控应用程序列表，可以指定多个监控的应用
applications =
[
  {
    // 监控应用ID号
    id = 0
    // 可执行程序全路径，可以指定为相对路径，指定为相对路径时，root不能为空
    exe = "/usr/src/d/bin/nvr"
    // 执行参数
    cmd = ""
    // 工具目录
    cwd = "/usr/src/d/bin"
    // 应用根目录
    root = ""
    // 是否为ui,windows启用ui需要开启特殊权限
    is_ui = 0
    // 同名应用控制策略 1 - 不允许再拉起同名 0 - 允许拉起多个同名应用
    policies=1
    // 监控类型，MonitorType_Supervise - 外部监控模式 MonitorType_IPC - 进程通信模式 ，需要应用程序定制开发
    monitor_type = "MonitorType_Supervise"
  }
]
</code></pre>
<h3 id="toc_16"><a name="toc_16" class="vnote-anchor" href="#"></a>3.3.3. 开机自启</h3>
<ul>
<li>windows下需要将softdog发布为服务</li>
</ul>
<pre><code class="hljs">cd {install}
softdog -install service_name
</code></pre>
<ul>
<li>linux下需要将启动脚本添加到开机启动项</li>
</ul>
<pre><code class="hljs">vi /etc/rc.local

// 文件末尾添加启动脚本
/usr/src/d/bin/nvrd.sh
</code></pre>
<h1 id="toc_17"><a name="toc_17" class="vnote-anchor" href="#"></a>4. 交互协议</h1>
<h2 id="toc_18"><a name="toc_18" class="vnote-anchor" href="#"></a>4.1. 设计原则</h2>
<p>HTTP接口遵循最简单原则，主要包括：</p>
<ul>
<li>只提供json数据格式接口，要求请求和响应的数据全都是json。</li>
<li>不提供html数据，譬如运行服务后，浏览器打开HTTP接口或HTTP服务地址，看到的是json，不是html。</li>
<li>发生错误时，支持HTTP错误码，或者json中的code错误码</li>
</ul>
<h2 id="toc_19"><a name="toc_19" class="vnote-anchor" href="#"></a>4.2. 交互格式</h2>
<h3 id="toc_20"><a name="toc_20" class="vnote-anchor" href="#"></a>4.2.1. 响应结果格式</h3>
<blockquote>
<p>HTTP协议头部</p>
</blockquote>
<pre><code class="hljs">    Connection: keep-alive
    Content-Length: 212
    Content-Type: application/json;charset=utf-8
    Date: Wed, May 01 2019 07:11:56 GMT
    Keep-Alive: timeout=10, max=100
    Server: RSS/1.0
</code></pre>
<p><strong>说明</strong></p>
<ul>
<li>结果类型均为application/json</li>
<li>结果默认字符集为utf-8</li>
</ul>
<blockquote>
<p>HTTP协议结果</p>
</blockquote>
<p>返回的结果使用json格式。</p>
<ul>
<li>返回单项值<pre><code class="hljs">{ "results": "value", "code": 0, "msg": "" }
</code></pre>
</li>
<li>返回数组<pre><code class="hljs">{ "results": [...], "code": 0, "msg": "" }
</code></pre>
</li>
<li>返回对象<pre><code class="hljs">{ "results": {...}, "code": 0, "msg": "" }
</code></pre>
</li>
<li>返回分页数据<pre><code class="hljs">{ "results": [...], "current_page":1, "total_page":2, "code": 0, "msg": "" }
</code></pre>
</li>
</ul>
<p><strong>说明</strong></p>
<ul>
<li><code>code</code>: 表示错误码，按照linux惯例，0表示成功。</li>
<li><code>msg</code>: 表示消息，错误时返回错误消息，成功时一般为空。</li>
<li><code>current_page</code>: 表示当前页。</li>
<li><code>total_page</code>: 表示总页数。</li>
<li><code>results</code>: 表示返回的数据。</li>
</ul>
<h3 id="toc_21"><a name="toc_21" class="vnote-anchor" href="#"></a>4.2.2. 错误码</h3>
<p>交互协议中，错误码由两种情况组成：</p>
<ul>
<li>返回<a href="#http_status_code_detail">HTTP 状态码</a>，即Status不等于200。</li>
<li>返回<a href="#http_api_code_detail">API 状态码</a>，即在HTTP Status为200时，响应的json的code不为0。</li>
</ul>
<p>在交互过程中应该处理这两种错误：</p>
<ul>
<li>返回HTTP错误：</li>
</ul>
<pre><code class="hljs">[root@dev ~]# curl -v http://192.168.31.240:18080/api/v1/test &amp;&amp; echo ""
&lt; HTTP/1.1 404 Not Found
&lt; Connection: Keep-Alive
&lt; Content-Length: 9
&lt; Content-Type: application/json; charset=utf-8
&lt; Server: RSS/1.0.0
&lt; 
Not Found

由于接口不存在而返回404错误。
</code></pre>
<ul>
<li>HTTP 200时协议code不等于0：</li>
</ul>
<pre><code class="hljs">[root@dev ~]# curl -v http://192.168.31.240:18080/api/v1/get_channel?channel=100 &amp;&amp; echo ""
&lt; HTTP/1.1 200 OK
&lt; Connection: Keep-Alive
&lt; Content-Length: 12
&lt; Content-Type: application/json; charset=utf-8
&lt; Server: RSS/1.0.0
&lt; 
{"code": 4, "msg": "通道号错误", "results":""}

由于通道号大于设备最大通道号，返回错误码4
</code></pre>
<h3 id="toc_22"><a name="toc_22" class="vnote-anchor" href="#"></a>4.2.3. 参数类型</h3>
<p>http接口返回参数均为json格式，接口中描述的参数为内部实现格式。在对参数序列化时请按接口给定类型进行赋值，下表为实现格式与json格式的对应关系：</p>
<table>
<thead>
<tr>
<th style="text-align:left">类型</th>
<th style="text-align:left">json类型</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">string</td>
<td style="text-align:left">string</td>
<td style="text-align:left">字符串</td>
</tr>
<tr>
<td style="text-align:left">bool</td>
<td style="text-align:left">bool</td>
<td style="text-align:left">布尔值</td>
</tr>
<tr>
<td style="text-align:left">int</td>
<td style="text-align:left">number</td>
<td style="text-align:left">整型</td>
</tr>
<tr>
<td style="text-align:left">long</td>
<td style="text-align:left">number</td>
<td style="text-align:left">长整型</td>
</tr>
<tr>
<td style="text-align:left">uint8</td>
<td style="text-align:left">number</td>
<td style="text-align:left">8位无符号整型</td>
</tr>
<tr>
<td style="text-align:left">uint32</td>
<td style="text-align:left">number</td>
<td style="text-align:left">32位无符号整型</td>
</tr>
<tr>
<td style="text-align:left">uint64</td>
<td style="text-align:left">number</td>
<td style="text-align:left">64位无符号整型</td>
</tr>
<tr>
<td style="text-align:left">object</td>
<td style="text-align:left">object</td>
<td style="text-align:left">对象</td>
</tr>
<tr>
<td style="text-align:left">array</td>
<td style="text-align:left">array</td>
<td style="text-align:left">数组对象</td>
</tr>
</tbody>
</table>
<h2 id="toc_23"><a name="toc_23" class="vnote-anchor" href="#"></a>4.3. 访问API</h2>
<h3 id="toc_24"><a name="toc_24" class="vnote-anchor" href="#"></a>4.3.1. 启用</h3>
<p>启动服务器：./nvr.sh</p>
<h3 id="toc_25"><a name="toc_25" class="vnote-anchor" href="#"></a>4.3.2. 使用</h3>
<p>访问API：浏览器打开地址http://192.168.31.240:18080/api/v1<br>
请注意：请将192.168.31.240或者下面提到的任何服务器IP，换成对应服务器的IP。</p>
<p><span id="what_is_http_callbacks_detail"></span></p>
<h2 id="toc_26"><a name="toc_26" class="vnote-anchor" href="#"></a>4.4. HTTP回调</h2>
<p>设备不仅支持HTTP API接口请求，还可以在完成指令后以HTTP回调形式接入其它平台，用于和第三方平台进行交互。可用回调参考<a href="#http_callbacks_detail">回调操作</a>。</p>
<ul>
<li>回调过程<br>
设备内部执行指令-&gt;操作完成-&gt;查询回调表-&gt;发送HTTP请求到第三方平台-&gt;返回响应信息到设备</li>
<li>回调数据<br>
回调均采用HTTP请求，所有数据均以application/json形式传输</li>
<li>回调响应<br>
在回调接收端处理完成回调后应按回调响应要求返回相应格式数据，设备以返回数据判定第三方平台是否正确处理回调。</li>
</ul>
<h2 id="toc_27"><a name="toc_27" class="vnote-anchor" href="#"></a>4.5. 约定术语</h2>
<p><span id="service_id_detail"></span></p>
<h3 id="toc_28"><a name="toc_28" class="vnote-anchor" href="#"></a>4.5.1. 服务标识</h3>
<p>设备支持使用过程中配置的热重启，每次启动服务都会生成一个服务server_id号用来标识服务器。<br>
客户端在获取信息时，必要时需要检查server_id是否改变，改变时就是服务已重启，之前所有的数据都应该作废了。</p>
<p><span id="stream_id_detail"></span></p>
<h3 id="toc_29"><a name="toc_29" class="vnote-anchor" href="#"></a>4.5.2. 流标识</h3>
<p>设备流的扭转均依靠流标识。流由vhost,app,stream三个值构成唯一标识。</p>
<ul>
<li>vhost: 虚拟主机</li>
<li>app:  应用名称</li>
<li>stream: 流名称</li>
</ul>
<h1 id="toc_30"><a name="toc_30" class="vnote-anchor" href="#"></a>5. API</h1>
<h2 id="toc_31"><a name="toc_31" class="vnote-anchor" href="#"></a>5.1. 基本信息</h2>
<h3 id="toc_32"><a name="toc_32" class="vnote-anchor" href="#"></a>5.1.1. 获取服务标识</h3>
<ul>
<li>
<p>接口说明<br>
获取到当前服务的标识信息，正如<a href="#service_id_detail">服务标识</a>所述，当<a href="#service_list_detail">服务</a>在进行热重启后数据信息可能会过期，使用service_id标识来标识是否一至，如果不一至，调用者需要刷新相应的信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": {
        "service_id": 0,
        "power_time": 1935267546,
        "start_time": 1935267546,
        "restart_time": 0,
        "duration": 1935286119,
        "total_duration": 18573
    },
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">service_id     {uint64} 服务标识id
power_time     {uint64} 硬件开机时间
start_time     {uint64} 服务最近一次开始时间
restart_time   {uint64} 服务最近一次重启时间 
duration       {uint64} 服务距最近一次开始时间时长
total_duration {uint64} 服务距开机时间总时长
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_33"><a name="toc_33" class="vnote-anchor" href="#"></a>5.1.2. 获取版本信息</h3>
<ul>
<li>
<p>接口说明<br>
获取到当前服务的版本信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/versions
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": {
        "name": "T100",
        "id": 88,
        "device_type": "RM-NVR-T100-01",
        "sn": "20190427C98011544",
        "major_version": "v1.0.0",
        "soft_version": "v1.0.0",
        "web_version": "v1.0.0",
        "api_version": "api/v1",
        "supply": "Ramsoft",
        "channel_num": 16,
        "disk_num": 1,
        "power_time": 18446744071572119561
    },
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">name           {string} 设备名称
id             {uint32} 设备编号
device_type    {string} 设备类型
sn             {string} 硬件序列号 
major_version  {string} 主版本号
soft_version   {string} 软件版本号
web_version    {string} 网页版本号
api_version    {string} 接口版本号
supply         {string} 制造厂商
channel_num    {uint32} 通道总数
disk_num       {uint32} 硬盘总数
power_time     {uint64} 设备开机时间
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_34"><a name="toc_34" class="vnote-anchor" href="#"></a>5.1.3. 获取设备简要信息[开发中]</h3>
<ul>
<li>
<p>接口说明<br>
获取设备简要描述信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/summaries
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": {
        "cpus": 2,
        "cpu_percent": 0.00289215180815393
    },
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">cpus           {uint32}  cpu数量
cpu_percent    {double}  cpu使用占比
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_35"><a name="toc_35" class="vnote-anchor" href="#"></a>5.1.4. 获取服务进程信息[开发中]</h3>
<ul>
<li>
<p>接口说明<br>
获取系统服务进程监控信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/system_proc_stats
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_36"><a name="toc_36" class="vnote-anchor" href="#"></a>5.1.5. 获取服务内存信息[开发中]</h3>
<ul>
<li>
<p>接口说明<br>
获取程序占用内存信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/meminfos
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<h3 id="toc_37"><a name="toc_37" class="vnote-anchor" href="#"></a>5.1.6. 获取设备硬盘信息[开发中]</h3>
<ul>
<li>
<p>接口说明<br>
获取系统硬盘使用情况信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/rusages
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<h2 id="toc_38"><a name="toc_38" class="vnote-anchor" href="#"></a>5.2. 通道配置</h2>
<h3 id="toc_39"><a name="toc_39" class="vnote-anchor" href="#"></a>5.2.1. 设置通道</h3>
<ul>
<li>
<p>接口说明<br>
设备通道拉流信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/set_channel?channel=1&amp;name=channel1&amp;url=rtsp://admin:Admin123@192.168.31.65/H.264/ch1/sub/av_stream&amp;vhost=__defaultVhost__&amp;app=live&amp;stream=1
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {uint32} [require]  流通道号
name          {string} [optional] 流通名称，未指定时默认规则为channel{x}(channel+通道序号)
url           {string} [require]  拉流地址
vhost         {string} [require]  流虚拟主机地址
app           {string} [require]  流应用名称
stream        {string} [require]  流名称
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_40"><a name="toc_40" class="vnote-anchor" href="#"></a>5.2.2. 设置通道是否可用</h3>
<ul>
<li>
<p>接口说明<br>
设置通道是否可用。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/set_channel_enable?channel=1&amp;enable=false
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {uint32} [require]  流通道号
enable        {bool}   [require]  是否可用
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_41"><a name="toc_41" class="vnote-anchor" href="#"></a>5.2.3. 设置通道是否按需[开发中]</h3>
<ul>
<li>
<p>接口说明<br>
设置通道按需拉流。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/set_channel_on_demand?channel=1&amp;on_demand=false
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {uint32} [require]  流通道号
on_demand     {bool}   [require]  是否按需求拉流
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_42"><a name="toc_42" class="vnote-anchor" href="#"></a>5.2.4. 获取通道信息</h3>
<ul>
<li>
<p>接口说明<br>
获取通道详细信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_channel?channel=1
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {string}  [require] 通道号
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">channel   {string} 通道号
enable    {bool}   是否可用
on_demand {bool}   是否按需		
name      {string} 通道名称		  
schema    {string} 协议类型
host      {string} 通道主机地址
port      {uint32} 通道主机端口
vhost     {string} 通道虚拟主机地址
app       {string} 通道应用名称
stream    {string} 通道流名称
url       {string} 通道拉流地址
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_43"><a name="toc_43" class="vnote-anchor" href="#"></a>5.2.5. 获取在用通道</h3>
<ul>
<li>
<p>接口说明<br>
获取所有正在工作的通道。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_active_channels
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": [
		{
            "channel": 2,
            "enable": false,
            "on_demand": false,
            "name": "",
            "schema": "rtsp",
            "host": "192.168.31.65",
            "port": 554,
            "username": "",
            "password": "",
            "vhost": "__defaultVhost__",
            "app": "live",
            "stream": "2",
            "url": "rtsp://184.72.239.149/vod/mp4:/BigBuckBunny_175k.mov"
        },
		...
	],
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">results   {array}  通道信息数组
          - channel   {string} 通道号
          - enable    {bool}   是否可用
          - on_demand {bool}   是否按需		
          - name      {string} 通道名称		  
          - schema    {string} 协议类型
          - host      {string} 通道主机地址
          - port      {uint32} 通道主机端口
          - vhost     {string} 通道虚拟主机地址
          - app       {string} 通道应用名称
          - stream    {string} 通道流名称
          - url       {string} 通道拉流地址
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_44"><a name="toc_44" class="vnote-anchor" href="#"></a>5.2.6. 获取所有通道</h3>
<ul>
<li>
<p>接口说明<br>
获取所有的通道信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_channels
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": [
		{
            "channel": 2,
            "enable": false,
            "on_demand": false,
            "name": "",
            "schema": "rtsp",
            "host": "192.168.31.65",
            "port": 554,
            "username": "",
            "password": "",
            "vhost": "__defaultVhost__",
            "app": "live",
            "stream": "2",
            "url": "rtsp://184.72.239.149/vod/mp4:/BigBuckBunny_175k.mov"
        },
		...
	],
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">results   {array}  通道信息数组
          - channel   {string} 通道号
          - enable    {bool}   是否可用
          - on_demand {bool}   是否按需		
          - name      {string} 通道名称		  
          - schema    {string} 协议类型
          - host      {string} 通道主机地址
          - port      {uint32} 通道主机端口
          - vhost     {string} 通道虚拟主机地址
          - app       {string} 通道应用名称
          - stream    {string} 通道流名称
          - url       {string} 通道拉流地址
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_45"><a name="toc_45" class="vnote-anchor" href="#"></a>5.2.7. 开始播放某个通道</h3>
<ul>
<li>
<p>接口说明<br>
开始某个通道拉流。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/start_channel?channel=14
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {string}  [require] 通道号
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_46"><a name="toc_46" class="vnote-anchor" href="#"></a>5.2.8. 停止播放某个通道</h3>
<ul>
<li>
<p>接口说明<br>
停止某个通道拉流。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/stop_channel?channel=2
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {string}  [require] 通道号
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h2 id="toc_47"><a name="toc_47" class="vnote-anchor" href="#"></a>5.3. 推流操作</h2>
<h3 id="toc_48"><a name="toc_48" class="vnote-anchor" href="#"></a>5.3.1. 设置推流地址</h3>
<ul>
<li>
<p>接口说明<br>
按推流地址设置推流器信息。调用接口后会解析推流地址，分别得到vhost，app，stream三个值。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/set_pusher?channel=1&amp;url=rtmp://192.168.31.240/live/0
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {string}  [require] 通道号
url           {string}  [require] 推流地址
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_49"><a name="toc_49" class="vnote-anchor" href="#"></a>5.3.2. 推某通道流</h3>
<ul>
<li>
<p>接口说明<br>
开始某通道推流。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/push_channel?channel=2
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {string}  [require] 通道号
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_50"><a name="toc_50" class="vnote-anchor" href="#"></a>5.3.3. 停止某路推流</h3>
<ul>
<li>
<p>接口说明<br>
停止推流。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/stop_push_channel?channel=2
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {string}  [require] 通道号
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_51"><a name="toc_51" class="vnote-anchor" href="#"></a>5.3.4. 设置推流通道[测试中]</h3>
<ul>
<li>
<p>接口说明<br>
作用和set_pusher一至，区别是set_pusher是解析推流地址后解析获取相关信息，而按流信息配置推流通道是直接赋值给推流。调用接口后会根据vhost，app，stream三个值生成推流地址。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/set_stream_pusher?channel=1&amp;schema=rtmp&amp;host=192.168.31.240&amp;vhost=__defaultVhost__&amp;port=1935&amp;app=live&amp;stream=0
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {string}  [require] 通道号
schema        {string}  [require] 协议类型
host          {string}  [require] 推流主机地址
vhost         {string}  [require] 推流所用通道的虚拟主机地址
app           {string}  [require] 推流所用的通道的应用名称
stream        {string}  [require] 推流所用的通道的流名称
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_52"><a name="toc_52" class="vnote-anchor" href="#"></a>5.3.5. 获取推流器信息</h3>
<ul>
<li>
<p>接口说明<br>
按指定的通道号返回推流器信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_pusher?channel=1
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {string}  [require] 通道号
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": {
        "name": "",
        "enable": true,
        "schema": "rtmp",
        "host": "192.168.31.189",
        "port": -1,
        "vhost": "__defaultVhost__",
        "app": "live",
        "stream": "1",
        "url": "rtmp://192.168.31.189/sa/1"
    },
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">name      {string} 推流器名称
enable    {bool}   是否可用
schema    {string} 推流协议类型
host      {string} 推流主机地址
port      {uint32} 推流主机端口
vhost     {string} 推流所用通道的虚拟主机地址
app       {string} 推流所用的通道的应用名称
stream    {string} 推流所用的通道的流名称
url       {string} 推流地址
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_53"><a name="toc_53" class="vnote-anchor" href="#"></a>5.3.6. 获取在用推流器</h3>
<ul>
<li>
<p>接口说明<br>
获取所有正在推流的推流器信息列表。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_active_pushers
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": [
        {
            "channel": 1,
            "schema": "rtmp",
            "host": "192.168.31.189",
            "port": -1,
            "vhost": "__defaultVhost__",
            "app": "live",
            "stream": "1",
            "url": "rtmp://192.168.31.189/sa/1"
        }
    ],
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">results    {array} 返回虚拟主机信息数组
           - channel   {string} 通道号
           - schema    {string} 推流协议类型
           - host      {string} 推流主机地址
           - port      {uint32} 推流主机端口
           - vhost     {string} 推流所用通道的虚拟主机地址
           - app       {string} 推流所用的通道的应用名称
           - stream    {string} 推流所用的通道的流名称
           - url       {string} 推流地址
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_54"><a name="toc_54" class="vnote-anchor" href="#"></a>5.3.7. 获取推流器状态</h3>
<ul>
<li>
<p>接口说明<br>
返回指定通道号所在推流器工作状态。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_pusher_state?channel=1
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {uint32}  [require]  通道号
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": {
        "channel": 1,
        "state": 0,
        "create": 18446744072868455308,
        "pre_try": 0,
        "pre_failed": 0,
        "try_times": 0,
        "pre_start": 0,
        "pre_stop": 0,
        "start": 18446744072868509434,
        "duration": 309461923
    },
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">channel       {uint32} 推流器通道号
state         {uint8}  推流器状态值
create        {uint64} 推流器创建时间
pre_try       {uint64} 推流器上一次重试的时间，如果从没有重试一直为0
pre_failed    {uint64} 推流器上一次重试失败时间，只要重试失败，该值将被覆盖
try_times     {uint64} 重试次数
pre_start     {uint64} 上一次推流成功的时间
pre_stop      {uint64} 上一次推流结束的时间
start         {uint64} 本次成功推流开始时间
duration      {uint64} 距本次成功推流的时长
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h2 id="toc_55"><a name="toc_55" class="vnote-anchor" href="#"></a>5.4. 流信息操作</h2>
<h3 id="toc_56"><a name="toc_56" class="vnote-anchor" href="#"></a>5.4.1. 获取虚拟主机</h3>
<ul>
<li>
<p>接口说明<br>
获取所有的vhost。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/vhosts
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": [
        {
            "vhost": "__defaultVhost__",
            "streams": 2
        }
    ],
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">results {array} 返回虚拟主机信息数组
        - vhost   {string} 虚拟主机名称
        - streams {uint32} 虚拟主机下在线的流数量
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_57"><a name="toc_57" class="vnote-anchor" href="#"></a>5.4.2. 获取所有流</h3>
<ul>
<li>
<p>接口说明<br>
获取所有正在播放的流。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/streams?schema=rtsp&amp;vhost=bytelink.cn&amp;app=live
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">schema     {string} [optional] 流协议类型，rtsp/rtmp
vhost      {string} [optional] 虚拟主机地址
app        {string} [optional] 应用地址
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": [
        {
            "schema": "rtmp",
            "vhost": "__defaultVhost__",
            "app": "live",
            "stream": "3"
        },
        {
            "schema": "rtsp",
            "vhost": "__defaultVhost__",
            "app": "live",
            "stream": "3"
        }
    ],
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">results         {array}   流信息数组
                - schema  {string}  协议类型
                - vhost   {string}  虚拟主机
                - app     {string}  应用名称
                - stream  {string}  流名称
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_58"><a name="toc_58" class="vnote-anchor" href="#"></a>5.4.3. 获取码流地址</h3>
<ul>
<li>请求接口</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_device_stream?channel=1&amp;schema=flv
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {uint32} [require]  流通道号
schema        {string} [require]  流协议类型
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": {
        "schema": "flv",
        "vhost": "__defaultVhost__",
        "app": "live",
        "stream": "1",
        "url": "http://192.168.31.240/live/1.flv",
        "can_play": true,
        "play_url": "http://192.168.31.240/live/1.flv"
    },
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">schema      {string} 流协议类型
vhost       {string} 虚拟主机地址
app         {string} 应用名称
stream      {string} 流名称
url         {string} 流完整地址
can_play    {bool}   是否能播放
play_url    {string} 流播放地址  
            - can_play为true，返回可播放的地址  
            - can_play为false，返回为空      
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0                           {int}   返回成功
LIVE_DEV_DVR_CHANNEL_ERROR  {int}   通道号错误
LIVE_DEV_DVR_PARAMETER_ERROR{int}   参数错误
</code></pre>
<h3 id="toc_59"><a name="toc_59" class="vnote-anchor" href="#"></a>5.4.4. 获取流状态</h3>
<ul>
<li>请求接口</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_channel_state?channel=1
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {uint32} [require] 流通道号
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": {
        "channel": 1,
        "state": 0,
        "create": 1556936530409,
        "pre_try": 1556939684923,
        "pre_failed": 1556939682922,
        "try_times": 1,
        "pre_start": 1556936530445,
        "pre_stop": 1556939682921,
        "start": 1556939685087,
        "duration": 14551166
    },
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">channel       {uint32} 流通道号
state         {uint8}  流状态值
create        {uint64} 通道创建时间
pre_try       {uint64} 流上一次重试播放时的时间，如果从没有重试一直为0
pre_failed    {uint64} 流上一次重试播放失败时间，只要重试播放失败，该值将被覆盖
try_times     {uint64} 重试次数
pre_start     {uint64} 上一次播放成功的时间
pre_stop      {uint64} 上一次播放结束的时间
start         {uint64} 本次成功播放开始时间
duration      {uint64} 距本次成功播放的时长
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h2 id="toc_60"><a name="toc_60" class="vnote-anchor" href="#"></a>5.5. 截图</h2>
<h3 id="toc_61"><a name="toc_61" class="vnote-anchor" href="#"></a>5.5.1. 获取封面截图</h3>
<ul>
<li>请求接口</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_cover?channel=1&amp;schema=http
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {uint32} [optional] 通道号，如果通道号没有指定，则查询所有可用通道
schema        {string} [optional] 预览地址类型，如果没有指定，服务默认为http
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": [
        {
            "channel": 1,
            "schema": "http",
            "cover_url": "http://192.168.31.240/cover/live/1/0.jpg"
        }
    ],
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">results {array} 封面截图信息数组
        - channel {uint32} 通道信息
        - schema  {string} 封面预览地址访问协议类型
        - cover_url {string} 封面截图预览地址
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   成功
</code></pre>
<h2 id="toc_62"><a name="toc_62" class="vnote-anchor" href="#"></a>5.6. 功能启停</h2>
<h3 id="toc_63"><a name="toc_63" class="vnote-anchor" href="#"></a>5.6.1. 设置功能码</h3>
<ul>
<li>
<p>接口说明<br>
设置通道功能码。设置通道功能码后该功能不会被立即调用。详见<a href="#set_channel_feature_detail">功能启停</a></p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/set_channel_mode?channel=1&amp;mode=2&amp;enable=true
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {string}  [require] 通道号
mode          {uint32}  [require] 功能码
enable        {bool}    [require] 功能是否启用
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">{
    "results": {
        "id": 2,
        "enable": false,
        "action": "on_play",
        "url": "",
        "desc": "播放回调"
    },
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功

</code></pre>
<p><span id="set_channel_feature_detail"></span></p>
<h3 id="toc_64"><a name="toc_64" class="vnote-anchor" href="#"></a>5.6.2. 设备功能启停</h3>
<ul>
<li>
<p>接口说明<br>
注意与功能push_channel/stop_pusher/等功能的区别。本功能的状态是立即生效并写入配置。<br>
执行过程为：
a、变更设备内存功能值
b、重载设备功能项
c、如果操作成功进行持久化操作，下次启动使用配置值</p>
<p>如开始推流功能可以使用以下步骤代替：</p>
<pre><code class="hljs">  step 1：设置通道模式功能情况，功能不会立即生效，需要等到设备重启后生效  
  http://192.168.31.240:18080/api/v1/set_channel_mode?channel=1&amp;mode=2&amp;enable=true  
  step 2：开始推流  
  http://192.168.31.240:18080/api/v1/push_channel?channel=1 
</code></pre>
<p>支持立即生成的功能有：</p>
<table>
<thead>
<tr>
<th style="text-align:left">功能码</th>
<th style="text-align:left">功能</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">work_mode_push</td>
<td style="text-align:left">推流</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">work_mode_capture</td>
<td style="text-align:left">定时截图</td>
<td style="text-align:left"></td>
</tr>
</tbody>
</table>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/set_channel_feature?channel=1&amp;feature=4&amp;enable=true
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {uint32} [require] 通道号，如果通道号没有指定，则查询所有可用通道
feature       {uint32} [require] 功能码，请查看功能码对应具体功能码
enable        {bool}   [require] 是否启用
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   成功
</code></pre>
<h3 id="toc_65"><a name="toc_65" class="vnote-anchor" href="#"></a>5.6.3. 查看功能状态</h3>
<ul>
<li>
<p>接口说明<br>
查询指定通道已开启的<a href="#channel_feature_detail">功能</a>。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_channel_feature?channel=1
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">channel       {uint32} [optional] 通道号，如果通道号没有指定，则查询所有可用通道
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": [
        {
            "channel": 1,
            "features": 7
        }
    ],
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">results {array} 通道功能信息数组
        - channel  {uint32} 通道信息
        - features {uint32} 已启用功能。它是一个复合字段。
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   成功
</code></pre>
<h2 id="toc_66"><a name="toc_66" class="vnote-anchor" href="#"></a>5.7. 平台接入</h2>
<h3 id="toc_67"><a name="toc_67" class="vnote-anchor" href="#"></a>5.7.1. 设置心跳</h3>
<ul>
<li>
<p>接口说明<br>
设置设备启停心跳功能。设置会将配置值写入配置文件。设置成功后立即生效，根据设置的状态值将执行：<br>
<strong>开启</strong> 按照心跳超时时间定时执行心跳操作，如果回调接口<a href="#on_keep_alive_detail">on_keep_alive</a> 已设置，将向指定的地址发送心跳数据<br>
<strong>关闭</strong> 如果之前已开启心跳，将停止心跳，如果没有开启将忽略操作。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/set_keep_alive?keep_alive=true
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">keep_alive       {bool} [require] 是否启用心跳
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   成功
</code></pre>
<h2 id="toc_68"><a name="toc_68" class="vnote-anchor" href="#"></a>5.8. 回调操作</h2>
<p>服务器端定制有一个重要的替代功能，就是HTTP回调。譬如当配置盒子推流到平台，回调指定的http地址获取是否具有推流权限，这样可以实现推流权限控制、按需推流等功能。</p>
<p><strong>注意</strong> 回调操作暂时不支持token验证</p>
<p><span id="http_callbacks_detail"></span></p>
<h3 id="toc_69"><a name="toc_69" class="vnote-anchor" href="#"></a>5.8.1. 设置回调</h3>
<ul>
<li>
<p>接口说明<br>
设置http hooks。可以设置的回调参考下表。回调时请求参数请参考对应说明。</p>
<table>
<thead>
<tr>
<th style="text-align:left">回调</th>
<th style="text-align:center">说明</th>
<th style="text-align:center">请求参数</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">on_play</td>
<td style="text-align:center">播放成功</td>
<td style="text-align:center"><a href="#on_play_detail">参数</a></td>
</tr>
<tr>
<td style="text-align:left">on_teardown</td>
<td style="text-align:center">关闭播放</td>
<td style="text-align:center"><a href="#on_teardown_detail">参数</a></td>
</tr>
<tr>
<td style="text-align:left">on_push</td>
<td style="text-align:center">推送成功</td>
<td style="text-align:center"><a href="#on_push_detail">参数</a></td>
</tr>
<tr>
<td style="text-align:left">on_unpush</td>
<td style="text-align:center">关闭推送</td>
<td style="text-align:center"><a href="#on_unpush_detail">参数</a></td>
</tr>
<tr>
<td style="text-align:left">on_register</td>
<td style="text-align:center">设备注册</td>
<td style="text-align:center"><a href="#on_register_detail">参数</a></td>
</tr>
<tr>
<td style="text-align:left">on_keep_alive</td>
<td style="text-align:center">设备接入平台时保活</td>
<td style="text-align:center"><a href="#on_keep_alive_detail">参数</a></td>
</tr>
<tr>
<td style="text-align:left">on_push_auth</td>
<td style="text-align:center">设备推流认证</td>
<td style="text-align:center"><a href="#on_push_auth_detail">参数</a></td>
</tr>
</tbody>
</table>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/set_callback?action=on_push&amp;url=http://192.168.31.240:18080/api/v1/on_push&amp;desc=推流回调
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">key       {string} 写入配置的键，例如"server.port"
value     {string} 写入配置的值
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_70"><a name="toc_70" class="vnote-anchor" href="#"></a>5.8.2. 新增回调</h3>
<ul>
<li>请求接口</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/add_callback?action=on_keep_alive&amp;url=http://192.168.31.240:18080/api/v1/on_keep_alive&amp;desc=心跳&amp;enable=true
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">key       {string} 写入配置的键，例如"server.port"
value     {string} 写入配置的值
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_71"><a name="toc_71" class="vnote-anchor" href="#"></a>5.8.3. 获取回调</h3>
<ul>
<li>
<p>接口说明<br>
获取回调接口信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_callback?action=on_play
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">key       {string} 写入配置的键，例如"server.port"
value     {string} 写入配置的值
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">{
    "results": {
        "id": 2,
        "enable": false,
        "action": "on_play",
        "url": "",
        "desc": "播放回调"
    },
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_72"><a name="toc_72" class="vnote-anchor" href="#"></a>5.8.4. 获取所有回调</h3>
<ul>
<li>
<p>接口说明<br>
获取所有回调接口信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_callbacks
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">key       {string} 写入配置的键，例如"server.port"
value     {string} 写入配置的值
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">{
    "results": {
        "id": 2,
        "enable": false,
        "action": "on_play",
        "url": "",
        "desc": "播放回调"
    },
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_73"><a name="toc_73" class="vnote-anchor" href="#"></a>5.8.5. 重载回调</h3>
<ul>
<li>
<p>接口说明<br>
重新刷新所有通道的回调信息。信息刷新后通道回调不会被立即调用，直到下一次事件触发时回调。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/reload_channel_callback?channel=1&amp;action=on_push
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">key       {string} 写入配置的键，例如"server.port"
value     {string} 写入配置的值
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">{
    "results": {
        "id": 2,
        "enable": false,
        "action": "on_play",
        "url": "",
        "desc": "播放回调"
    },
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_74"><a name="toc_74" class="vnote-anchor" href="#"></a>5.8.6. 回调详情</h3>
<h4 id="toc_75"><a name="toc_75" class="vnote-anchor" href="#"></a>5.8.6.1. on_register - 设备注册</h4>
<ul>
<li>事件</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/on_register
</code></pre>
<ul>
<li>数据</li>
</ul>
<pre><code class="hljs">{
  "action": "on_push",
  "state": 1,
  "channel": 1985,
  "host":"192.168.31.240",
  "port":1935,
  "ip": "192.168.1.10", 
  "vhost": "__defaultVhost__", 
  "app": "live",
  "stream": "livestream",
  "url":""
}
</code></pre>
<ul>
<li>参数说明</li>
</ul>
<pre><code class="hljs">action       {string} 事件类型
state        {string} 状态值
</code></pre>
<ul>
<li>响应要求</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h4 id="toc_76"><a name="toc_76" class="vnote-anchor" href="#"></a>5.8.6.2. on_keep_alive - 设备接入心跳</h4>
<ul>
<li>事件</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/on_keep_alive
</code></pre>
<ul>
<li>数据</li>
</ul>
<pre><code class="hljs">{
  "action": "on_push",
  "state": "on_push",
  "channel": 1985,
  "host":"192.168.31.240",
  "port":1935,
  "ip": "192.168.1.10", 
  "vhost": "video.test.com", 
  "app": "live",
  "stream": "livestream",
  "url":""
}
</code></pre>
<ul>
<li>参数说明</li>
</ul>
<pre><code class="hljs">action       {string} 事件类型
state        {string} 状态值
</code></pre>
<ul>
<li>响应要求</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h4 id="toc_77"><a name="toc_77" class="vnote-anchor" href="#"></a>5.8.6.3. on_play - 成功播放</h4>
<ul>
<li>事件</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/on_play
</code></pre>
<ul>
<li>数据</li>
</ul>
<pre><code class="hljs">{
  "action": "on_push",
  "state": "on_push",
  "channel": 1985,
  "host":"192.168.31.240",
  "port":1935,
  "ip": "192.168.1.10", 
  "vhost": "video.test.com", 
  "app": "live",
  "stream": "livestream",
  "url":""
}
</code></pre>
<ul>
<li>参数说明</li>
</ul>
<pre><code class="hljs">action       {string} 事件类型
state        {string} 状态值
</code></pre>
<ul>
<li>响应要求</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h4 id="toc_78"><a name="toc_78" class="vnote-anchor" href="#"></a>5.8.6.4. on_teardown - 停止播放</h4>
<ul>
<li>事件</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/on_teardown
</code></pre>
<ul>
<li>数据</li>
</ul>
<pre><code class="hljs">{
  "action": "on_push",
  "state": "on_push",
  "channel": 1985,
  "host":"192.168.31.240",
  "port":1935,
  "ip": "192.168.1.10", 
  "vhost": "video.test.com", 
  "app": "live",
  "stream": "livestream",
  "url":""
}
</code></pre>
<ul>
<li>参数说明</li>
</ul>
<pre><code class="hljs">action       {string} 事件类型
state        {string} 状态值
</code></pre>
<ul>
<li>响应要求</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<p><span id="on_push_detail"></span></p>
<h4 id="toc_79"><a name="toc_79" class="vnote-anchor" href="#"></a>5.8.6.5. on_push - 推流成功</h4>
<ul>
<li>事件</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/on_push
</code></pre>
<ul>
<li>数据</li>
</ul>
<pre><code class="hljs">{
  "action": "on_push",
  "state": "on_push",
  "channel": 1985,
  "host":"192.168.31.240",
  "port":1935,
  "ip": "192.168.1.10", 
  "vhost": "video.test.com", 
  "app": "live",
  "stream": "livestream",
  "url":""
}
</code></pre>
<ul>
<li>参数说明</li>
</ul>
<pre><code class="hljs">action       {string} 事件类型
state        {string} 状态值
</code></pre>
<ul>
<li>响应要求</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h4 id="toc_80"><a name="toc_80" class="vnote-anchor" href="#"></a>5.8.6.6. on_unpush - 停止推流</h4>
<ul>
<li>事件</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/on_unpush
</code></pre>
<ul>
<li>数据</li>
</ul>
<pre><code class="hljs">{
  "action": "on_push",
  "state": "on_push",
  "channel": 1985,
  "host":"192.168.31.240",
  "port":1935,
  "ip": "192.168.1.10", 
  "vhost": "video.test.com", 
  "app": "live",
  "stream": "livestream",
  "url":""
}
</code></pre>
<ul>
<li>参数说明</li>
</ul>
<pre><code class="hljs">action       {string} 事件类型
state        {string} 状态值
</code></pre>
<ul>
<li>响应要求</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h4 id="toc_81"><a name="toc_81" class="vnote-anchor" href="#"></a>5.8.6.7. on_push_auth - 推流认证</h4>
<ul>
<li>事件</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/on_push_auth
</code></pre>
<ul>
<li>数据</li>
</ul>
<pre><code class="hljs">{
  "action": "on_push",
  "state": "on_push",
  "channel": 1985,
  "host":"192.168.31.240",
  "port":1935,
  "ip": "192.168.1.10", 
  "vhost": "video.test.com", 
  "app": "live",
  "stream": "livestream",
  "url":""
}
</code></pre>
<ul>
<li>参数说明</li>
</ul>
<pre><code class="hljs">action       {string} 事件类型
state        {string} 状态值
</code></pre>
<ul>
<li>响应要求</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h4 id="toc_82"><a name="toc_82" class="vnote-anchor" href="#"></a>5.8.6.8. on_capture - 抓图成功</h4>
<ul>
<li>事件</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/on_capture
</code></pre>
<ul>
<li>数据</li>
</ul>
<pre><code class="hljs">{
  "action": "on_push",
  "state": "on_push",
  "channel": 1985,
  "host":"192.168.31.240",
  "port":1935,
  "ip": "192.168.1.10", 
  "vhost": "video.test.com", 
  "app": "live",
  "stream": "livestream",
  "url":""
}
</code></pre>
<ul>
<li>参数说明</li>
</ul>
<pre><code class="hljs">action       {string} 事件类型
state        {string} 状态值
</code></pre>
<ul>
<li>响应要求</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h2 id="toc_83"><a name="toc_83" class="vnote-anchor" href="#"></a>5.9. 服务配置</h2>
<h3 id="toc_84"><a name="toc_84" class="vnote-anchor" href="#"></a>5.9.1. 写入配置</h3>
<ul>
<li>
<p>接口说明<br>
写入配置信息。配置信息写入后支持热重载，写入后会对服务进行热重载。请查看<a href="#hot_reload_detail">热重载配置</a>。
写入的配置必须具有可写权限。参考<a href="#config_mod_table_detail">配置权限列表</a>查看配置是否具有可写权限。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/set_config?key=server.keep_alive&amp;value=true
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">key       {string} [require] 写入配置的键，例如"server.port"
value     {string} [require] 写入配置的值
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<h3 id="toc_85"><a name="toc_85" class="vnote-anchor" href="#"></a>5.9.2. 获取配置</h3>
<ul>
<li>
<p>接口说明<br>
获取配置信息。获取的配置信息必须具有可读权限。参考<a href="#config_mod_table_detail">配置权限列表</a>查看配置是否具有可读权限。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/get_config?key=server.keep_alive
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">key       {string} [require] 配置的键，例如"server.port"
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": {
        "server.keep_alive": "false"
    },
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">results         {object} 键值对
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   返回成功
</code></pre>
<p><span id="config_mod_table_detail"></span></p>
<h3 id="toc_86"><a name="toc_86" class="vnote-anchor" href="#"></a>5.9.3. 配置权限表[开发中]</h3>
<table>
<thead>
<tr>
<th style="text-align:left">配置</th>
<th style="text-align:center">可读</th>
<th style="text-align:center">可写</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">broadcast.flowThreshold</td>
<td style="text-align:center">是</td>
<td style="text-align:center">否</td>
<td style="text-align:left">流量汇报事件流量阈值,单位KB，默认1MB</td>
</tr>
<tr>
<td style="text-align:left">capture.appName</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">capture.filePath</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">capture.fileSecond</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">capture.enable</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">hls.fileBufSize</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">hls.filePath</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">hls.segDur</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">hls.segNum</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">http.charSet</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">http.keepAliveSecond</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">http.maxReqCount</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">http.maxReqSize</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">http.notFound</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">http.port</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">http.rootPath</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">http.sendBufSize</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">http.sslport</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">http.api_port</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">multicast.addrMax</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">multicast.addrMin</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">multicast.udpTTL</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">record.appName</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">record.filePath</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">record.fileSecond</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">record.sampleMS</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">rtmp.modifyStamp</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">rtmp.port</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">rtp.audioMtuSize</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">rtp.clearCount</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">rtp.cycleMS</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">rtp.maxRtpCount</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">rtp.videoMtuSize</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">rtsp.authBasic</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">rtsp.sslport</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">rtsp.segNum</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">server.db</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">server.host</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">server.keep_alive</td>
<td style="text-align:center">是</td>
<td style="text-align:center">是</td>
<td style="text-align:left">是否定时发送心跳</td>
</tr>
<tr>
<td style="text-align:left">server.keep_timeout</td>
<td style="text-align:center">是</td>
<td style="text-align:center">是</td>
<td style="text-align:left">设备心跳时间间隔，单位为秒</td>
</tr>
<tr>
<td style="text-align:left">shell.maxReqSize</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:left">shell.port</td>
<td style="text-align:center">否</td>
<td style="text-align:center">否</td>
<td style="text-align:left">-</td>
</tr>
</tbody>
</table>
<h2 id="toc_87"><a name="toc_87" class="vnote-anchor" href="#"></a>5.10. 系统配置</h2>
<h3 id="toc_88"><a name="toc_88" class="vnote-anchor" href="#"></a>5.10.1. 关机</h3>
<ul>
<li>
<p>接口说明<br>
设备关机。设置关机操作成功2秒后系统关机。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/sys_poweroff
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": "system power off after 2 seconds"
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   成功
</code></pre>
<h3 id="toc_89"><a name="toc_89" class="vnote-anchor" href="#"></a>5.10.2. 重启</h3>
<ul>
<li>
<p>接口说明<br>
设备重启。设置重启操作成功2秒后系统重启。如果是以发布模式启动程序时，系统重启后将再次运行守护进程程序，否则需要手动启动程序。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/sys_reboot
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": "system reboot after 2 seconds"
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   成功
</code></pre>
<h3 id="toc_90"><a name="toc_90" class="vnote-anchor" href="#"></a>5.10.3. 网络配置</h3>
<h4 id="toc_91"><a name="toc_91" class="vnote-anchor" href="#"></a>5.10.3.1. 获取网卡</h4>
<ul>
<li>
<p>接口说明<br>
获取设备所有可用网卡信息。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/net_interfaces
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">{
    "results": [
        {
            "name": "eth37",
            "type": "Ethernet",
            "adapter": "Intel(R) Dual Band Wireless-AC 8265",
            "mac": "d46d6d5b1ab7",
            "address": "192.168.31.240",
            "netmask": "255.255.255.0"
        },
        {
            "name": "eth14",
            "type": "Ethernet",
            "adapter": "Realtek Gaming GBE Family Controller",
            "mac": "d8c4973d4466",
            "address": "",
            "netmask": ""
        }
    ],
    "code": 0,
    "msg": ""
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">results          {array}   网卡信息数组
                 - name    {string}   网卡名称 
                 - type    {string}   网卡类型
                 - adapter {string}   适配器描述信息
                 - mac     {string}   网卡MAC地址
                 - address {string}   网卡工作IP地址
                 - netmask {string}   网卡工作子网掩码
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   成功
</code></pre>
<h4 id="toc_92"><a name="toc_92" class="vnote-anchor" href="#"></a>5.10.3.2. 设置静态IP</h4>
<ul>
<li>
<p>接口说明<br>
设置设备静态IP。设置成功后设备会重启服务。双网卡的情况下，如果是配置服务网卡，将重启服务，如果配置拉流内网地址，服务不重启。
<strong>注意</strong>  设置静态IP需要开启管理员权限。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/set_net_static?adapter=ens33&amp;ip=192.168.31.241&amp;netmask=255.255.255.0&amp;gateway=192.168.31.1&amp;dns1=8.8.8.8
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">adapter  {string} [require]   适配器名称，以查询获取的名称为准
ip       {string} [require]   IP地址
netmask  {string} [optional]  子网掩码，如果没有指定，将置为255.255.255.0
gateway  {string} [optional]  网关
dns1     {string} [optional]  DNS服务器地址
</code></pre>
<ul>
<li>响应说明
在配置拉流地址时返回，配置服务地址时网络断开连接，将接收不到服务信息。</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": "set net card success, please refresh for informations"
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   成功
</code></pre>
<h4 id="toc_93"><a name="toc_93" class="vnote-anchor" href="#"></a>5.10.3.3. 设置DHCP</h4>
<ul>
<li>
<p>接口说明<br>
设置设备动态获取IP。设置成功后设备会重启服务。双网卡的情况下，如果是配置服务网卡，将重启服务，如果配置拉流内网地址，服务不重启。
<strong>注意</strong>  设置静态IP需要开启管理员权限。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/set_net_dhcp?adapter=Realtek Gaming GBE Family Controller
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">adapter  {string} [require]   适配器名称，以查询获取的名称为准
</code></pre>
<ul>
<li>响应说明
在配置拉流地址时返回，配置服务地址时网络断开连接，将接收不到服务信息。</li>
</ul>
<pre><code class="hljs">{
    "results": "",
    "code": 0,
    "msg": "set net card success, please refresh for informations"
}
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">0               {int}   成功
</code></pre>
<h3 id="toc_94"><a name="toc_94" class="vnote-anchor" href="#"></a>5.10.4. 时间核对[开发中]</h3>
<ul>
<li>
<p>接口说明<br>
设置设备日期时间。</p>
</li>
<li>
<p>请求接口</p>
</li>
</ul>
<pre><code class="hljs">Method: GET
http://192.168.31.240:18080/api/v1/sys_set_datetime
</code></pre>
<ul>
<li>请求参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应说明</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>响应参数</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<ul>
<li>状态码</li>
</ul>
<pre><code class="hljs">-
</code></pre>
<h2 id="toc_95"><a name="toc_95" class="vnote-anchor" href="#"></a>5.11. 其它</h2>
<h3 id="toc_96"><a name="toc_96" class="vnote-anchor" href="#"></a>5.11.1. 推流完整过程</h3>
<pre><code class="hljs">* 配置回调信息  
http://192.168.31.240:18080/api/v1/add_callback?action=on_push&amp;url=http://192.168.31.240:18080/api/v1/on_push&amp;desc=推流回调信息  
http://192.168.31.240:18080/api/v1/add_callback?action=on_play&amp;url=http://192.168.31.240:18080/api/v1/on_play&amp;desc=拉流状态回调信息

* 配置通道信息  
http://192.168.31.240:18080/api/v1/set_channel?channel=1&amp;url=rtsp://admin:Admin123@192.168.31.64/H.264/ch1/sub/av_stream&amp;vhost=__defaultVhost__&amp;app=live&amp;stream=1
* 设置通道可用  
http://192.168.31.240:18080/api/v1/set_channel_enable?channel=1&amp;enable=true
* 拉取通道流  
http://192.168.31.240:18080/api/v1/start_channel?channel=1
* 设置推流器  
http://192.168.31.240:18080/api/v1/set_pusher?channel=1&amp;url=rtmp://192.168.31.240/schoolb/placeb  
* 设置通道模式为推流   
http://192.168.31.240:18080/api/v1/set_channel_mode?channel=1&amp;mode=2  
* 开始推流  
http://192.168.31.240:18080/api/v1/push_channel?channel=1  
</code></pre>
<h1 id="toc_97"><a name="toc_97" class="vnote-anchor" href="#"></a>6. 附录</h1>
<h2 id="toc_98"><a name="toc_98" class="vnote-anchor" href="#"></a>6.1. 状态码定义</h2>
<p><span id="http_status_code_detail"></span></p>
<h3 id="toc_99"><a name="toc_99" class="vnote-anchor" href="#"></a>6.1.1. HTTP状态码</h3>
<table>
<thead>
<tr>
<th style="text-align:center">状态码</th>
<th style="text-align:left">名称</th>
<th style="text-align:left">报文描述</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">100</td>
<td style="text-align:left">CONTINUE</td>
<td style="text-align:left">Continue</td>
<td style="text-align:left">继续，客户端应继续其请求</td>
</tr>
<tr>
<td style="text-align:center">101</td>
<td style="text-align:left">SWITCHING_PROTOCOLS</td>
<td style="text-align:left">Switching Protocols</td>
<td style="text-align:left">切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议，例如，切换到HTTP的新版本协议</td>
</tr>
<tr>
<td style="text-align:center">102</td>
<td style="text-align:left">PROCESSING</td>
<td style="text-align:left">Processing</td>
<td style="text-align:left">处理中</td>
</tr>
<tr>
<td style="text-align:center">200</td>
<td style="text-align:left">OK</td>
<td style="text-align:left">OK</td>
<td style="text-align:left">请求成功，一般用于GET与POST请求</td>
</tr>
<tr>
<td style="text-align:center">201</td>
<td style="text-align:left">CREATED</td>
<td style="text-align:left">Created</td>
<td style="text-align:left">已创建，成功请求并创建了新的资源</td>
</tr>
<tr>
<td style="text-align:center">202</td>
<td style="text-align:left">ACCEPTED</td>
<td style="text-align:left">Accepted</td>
<td style="text-align:left">已接收请求，但处理尚未完成</td>
</tr>
<tr>
<td style="text-align:center">203</td>
<td style="text-align:left">NON_AUTHORITATIVE_INFORMATION</td>
<td style="text-align:left">Non-Authoritative Information</td>
<td style="text-align:left">非授权信息。请求成功。但返回的meta信息不在原始的服务器，而是一个副本</td>
</tr>
<tr>
<td style="text-align:center">204</td>
<td style="text-align:left">NO_CONTENT</td>
<td style="text-align:left">No Content</td>
<td style="text-align:left">无内容。服务器成功处理，但未返回内容。在未更新网页的情况下，可确保浏览器继续显示当前文档</td>
</tr>
<tr>
<td style="text-align:center">205</td>
<td style="text-align:left">RESET_CONTENT</td>
<td style="text-align:left">Reset Content</td>
<td style="text-align:left">重置内容。服务器处理成功，用户终端（例如：浏览器）应重置文档视图。可通过此返回码清除浏览器的表单域</td>
</tr>
<tr>
<td style="text-align:center">206</td>
<td style="text-align:left">PARTIAL_CONTENT</td>
<td style="text-align:left">Partial Content</td>
<td style="text-align:left">部分内容。服务器成功处理了部分GET请求</td>
</tr>
<tr>
<td style="text-align:center">207</td>
<td style="text-align:left">MULTI_STATUS</td>
<td style="text-align:left">Multi-Status</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">208</td>
<td style="text-align:left">ALREADY_REPORTED</td>
<td style="text-align:left">Already Reported</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">226</td>
<td style="text-align:left">IM_USED</td>
<td style="text-align:left">IM Used</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">300</td>
<td style="text-align:left">MULTIPLE_CHOICES</td>
<td style="text-align:left">Multiple Choices</td>
<td style="text-align:left">多种选择。请求的资源可包括多个位置，相应可返回一个资源特征与地址的列表用于用户终端（例如：浏览器）选择</td>
</tr>
<tr>
<td style="text-align:center">301</td>
<td style="text-align:left">MOVED_PERMANENTLY</td>
<td style="text-align:left">Moved Permanently</td>
<td style="text-align:left">永久移动。请求的资源已被永久的移动到新URI，返回信息会包括新的URI，浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替</td>
</tr>
<tr>
<td style="text-align:center">302</td>
<td style="text-align:left">FOUND</td>
<td style="text-align:left">Found</td>
<td style="text-align:left">临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI</td>
</tr>
<tr>
<td style="text-align:center">303</td>
<td style="text-align:left">SEE_OTHER</td>
<td style="text-align:left">See Other</td>
<td style="text-align:left">查看其它地址。与301类似。使用GET和POST请求查看</td>
</tr>
<tr>
<td style="text-align:center">304</td>
<td style="text-align:left">NOT_MODIFIED</td>
<td style="text-align:left">Not Modified</td>
<td style="text-align:left">未修改。所请求的资源未修改，服务器返回此状态码时，不会返回任何资源。客户端通常会缓存访问过的资源，通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源</td>
</tr>
<tr>
<td style="text-align:center">305</td>
<td style="text-align:left">USE_PROXY</td>
<td style="text-align:left">Use Proxy</td>
<td style="text-align:left">使用代理。所请求的资源必须通过代理访问</td>
</tr>
<tr>
<td style="text-align:center">305</td>
<td style="text-align:left">-</td>
<td style="text-align:left">-</td>
<td style="text-align:left">已经被废弃的HTTP状态码</td>
</tr>
<tr>
<td style="text-align:center">307</td>
<td style="text-align:left">TEMPORARY_REDIRECT</td>
<td style="text-align:left">Temporary Redirect</td>
<td style="text-align:left">临时重定向。与302类似。使用GET请求重定向</td>
</tr>
<tr>
<td style="text-align:center">308</td>
<td style="text-align:left">PERMANENT_REDIRECT</td>
<td style="text-align:left">Permanent Redirect</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">400</td>
<td style="text-align:left">BAD_REQUEST</td>
<td style="text-align:left">Bad Request</td>
<td style="text-align:left">客户端请求的语法错误，服务器无法理解</td>
</tr>
<tr>
<td style="text-align:center">401</td>
<td style="text-align:left">UNAUTHORIZED</td>
<td style="text-align:left">Unauthorized</td>
<td style="text-align:left">请求要求用户的身份认证</td>
</tr>
<tr>
<td style="text-align:center">402</td>
<td style="text-align:left">PAYMENT_REQUIRED</td>
<td style="text-align:left">Payment Required</td>
<td style="text-align:left">保留，将来使用</td>
</tr>
<tr>
<td style="text-align:center">403</td>
<td style="text-align:left">FORBIDDEN</td>
<td style="text-align:left">Forbidden</td>
<td style="text-align:left">服务器理解请求客户端的请求，但是拒绝执行此请求</td>
</tr>
<tr>
<td style="text-align:center">404</td>
<td style="text-align:left">NOT_FOUND</td>
<td style="text-align:left">Not Found</td>
<td style="text-align:left">服务器无法根据客户端的请求找到资源（网页）</td>
</tr>
<tr>
<td style="text-align:center">405</td>
<td style="text-align:left">METHOD_NOT_ALLOWED</td>
<td style="text-align:left">Method Not Allowed</td>
<td style="text-align:left">客户端请求中的方法被禁止</td>
</tr>
<tr>
<td style="text-align:center">406</td>
<td style="text-align:left">NOT_ACCEPTABLE</td>
<td style="text-align:left">Not Acceptable</td>
<td style="text-align:left">服务器无法根据客户端请求的内容特性完成请求</td>
</tr>
<tr>
<td style="text-align:center">407</td>
<td style="text-align:left">PROXY_AUTHENTICATION_REQUIRED</td>
<td style="text-align:left">Proxy Authentication Required</td>
<td style="text-align:left">请求要求代理的身份认证，与401类似，但请求者应当使用代理进行授权</td>
</tr>
<tr>
<td style="text-align:center">408</td>
<td style="text-align:left">REQUEST_TIMEOUT</td>
<td style="text-align:left">Request Timeout</td>
<td style="text-align:left">服务器等待客户端发送的请求时间过长，超时</td>
</tr>
<tr>
<td style="text-align:center">409</td>
<td style="text-align:left">CONFLICT</td>
<td style="text-align:left">Conflict</td>
<td style="text-align:left">服务器完成客户端的PUT请求是可能返回此代码，服务器处理请求时发生了冲突</td>
</tr>
<tr>
<td style="text-align:center">410</td>
<td style="text-align:left">GONE</td>
<td style="text-align:left">Gone</td>
<td style="text-align:left">客户端请求的资源已经不存在。410不同于404，如果资源以前有现在被永久删除了可使用410代码，网站设计人员可通过301代码指定资源的新位置</td>
</tr>
<tr>
<td style="text-align:center">411</td>
<td style="text-align:left">LENGTH_REQUIRED</td>
<td style="text-align:left">Length Required</td>
<td style="text-align:left">服务器无法处理客户端发送的不带Content-Length的请求信息</td>
</tr>
<tr>
<td style="text-align:center">412</td>
<td style="text-align:left">PRECONDITION_FAILED</td>
<td style="text-align:left">Precondition Failed</td>
<td style="text-align:left">客户端请求信息的先决条件错误</td>
</tr>
<tr>
<td style="text-align:center">413</td>
<td style="text-align:left">PAYLOAD_TOO_LARGE</td>
<td style="text-align:left">Payload Too Large</td>
<td style="text-align:left">由于请求的实体过大，服务器无法处理，因此拒绝请求。为防止客户端的连续请求，服务器可能会关闭连接。如果只是服务器暂时无法处理，则会包含一个Retry-After的响应信息</td>
</tr>
<tr>
<td style="text-align:center">414</td>
<td style="text-align:left">URI_TOO_LONG</td>
<td style="text-align:left">URI Too Long</td>
<td style="text-align:left">请求的URI过长（URI通常为网址），服务器无法处理</td>
</tr>
<tr>
<td style="text-align:center">415</td>
<td style="text-align:left">UNSUPPORTED_MEDIA_TYPE</td>
<td style="text-align:left">Unsupported Media Type</td>
<td style="text-align:left">服务器无法处理请求附带的媒体格式</td>
</tr>
<tr>
<td style="text-align:center">416</td>
<td style="text-align:left">RANGE_NOT_SATISFIABLE</td>
<td style="text-align:left">Range Not Satisfiable</td>
<td style="text-align:left">客户端请求的范围无效</td>
</tr>
<tr>
<td style="text-align:center">417</td>
<td style="text-align:left">EXPECTATION_FAILED</td>
<td style="text-align:left">Expectation Failed</td>
<td style="text-align:left">服务器无法满足Expect的请求头信息</td>
</tr>
<tr>
<td style="text-align:center">421</td>
<td style="text-align:left">MISDIRECTED_REQUEST</td>
<td style="text-align:left">Misdirected Request</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">422</td>
<td style="text-align:left">UNPROCESSABLE_ENTITY</td>
<td style="text-align:left">Unprocessable Entity</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">423</td>
<td style="text-align:left">LOCKED</td>
<td style="text-align:left">Locked</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">424</td>
<td style="text-align:left">FAILED_DEPENDENCY</td>
<td style="text-align:left">Failed Dependency</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">426</td>
<td style="text-align:left">UPGRADE_REQUIRED</td>
<td style="text-align:left">Upgrade Required</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">428</td>
<td style="text-align:left">PRECONDITION_REQUIRED</td>
<td style="text-align:left">Precondition Required</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">429</td>
<td style="text-align:left">TOO_MANY_REQUESTS</td>
<td style="text-align:left">Too Many Requests</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">431</td>
<td style="text-align:left">REQUEST_HEADER_FIELDS_TOO_LARGE</td>
<td style="text-align:left">Request Header Fields Too Large</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">451</td>
<td style="text-align:left">UNAVAILABLE_FOR_LEGAL_REASONS</td>
<td style="text-align:left">Unavailable For Legal Reasons</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">500</td>
<td style="text-align:left">INTERNAL_SERVER_ERROR</td>
<td style="text-align:left">Internal Server Error</td>
<td style="text-align:left">服务器内部错误，无法完成请求</td>
</tr>
<tr>
<td style="text-align:center">501</td>
<td style="text-align:left">NOT_IMPLEMENTED</td>
<td style="text-align:left">Not Implemented</td>
<td style="text-align:left">服务器不支持请求的功能，无法完成请求</td>
</tr>
<tr>
<td style="text-align:center">502</td>
<td style="text-align:left">BAD_GATEWAY</td>
<td style="text-align:left">Bad Gateway</td>
<td style="text-align:left">作为网关或者代理工作的服务器尝试执行请求时，从远程服务器接收到了一个无效的响应</td>
</tr>
<tr>
<td style="text-align:center">503</td>
<td style="text-align:left">SERVICE_UNAVAILABLE</td>
<td style="text-align:left">Service Unavailable</td>
<td style="text-align:left">由于超载或系统维护，服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中</td>
</tr>
<tr>
<td style="text-align:center">504</td>
<td style="text-align:left">GATEWAY_TIMEOUT</td>
<td style="text-align:left">Gateway Timeout</td>
<td style="text-align:left">充当网关或代理的服务器，未及时从远端服务器获取请求</td>
</tr>
<tr>
<td style="text-align:center">505</td>
<td style="text-align:left">HTTP_VERSION_NOT_SUPPORTED</td>
<td style="text-align:left">HTTP Version Not Supported</td>
<td style="text-align:left">服务器不支持请求的HTTP协议的版本，无法完成处理</td>
</tr>
<tr>
<td style="text-align:center">506</td>
<td style="text-align:left">VARIANT_ALSO_NEGOTIATES</td>
<td style="text-align:left">Variant Also Negotiates</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">507</td>
<td style="text-align:left">INSUFFICIENT_STORAGE</td>
<td style="text-align:left">Insufficient Storage</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">508</td>
<td style="text-align:left">LOOP_DETECTED</td>
<td style="text-align:left">Loop Detected</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">510</td>
<td style="text-align:left">NOT_EXTENDED</td>
<td style="text-align:left">Not Extended</td>
<td style="text-align:left">-</td>
</tr>
<tr>
<td style="text-align:center">511</td>
<td style="text-align:left">NETWORK_AUTHENTICATION_REQUIRED</td>
<td style="text-align:left">Network Authentication Required</td>
<td style="text-align:left">-</td>
</tr>
</tbody>
</table>
<h3 id="toc_100"><a name="toc_100" class="vnote-anchor" href="#"></a>6.1.2. API状态码[开发中]</h3>
<table>
<thead>
<tr>
<th style="text-align:left">状态码</th>
<th style="text-align:left">名称</th>
<th style="text-align:left">报文描述</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">0</td>
<td style="text-align:left"></td>
<td style="text-align:left">success</td>
<td style="text-align:left">成功</td>
</tr>
<tr>
<td style="text-align:left">4</td>
<td style="text-align:left">LIVE_DEV_DVR_CHANNEL_ERROR</td>
<td style="text-align:left">channel number error</td>
<td style="text-align:left">通道号错误</td>
</tr>
</tbody>
</table>
<p><span id="channel_feature_detail"></span></p>
<h4 id="toc_101"><a name="toc_101" class="vnote-anchor" href="#"></a>6.1.2.1. 功能码</h4>
<table>
<thead>
<tr>
<th style="text-align:left">枚举值</th>
<th style="text-align:left">值</th>
<th style="text-align:left">描述</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">work_mode_none</td>
<td style="text-align:left">0x0</td>
<td style="text-align:left">无</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">work_mode_ingest</td>
<td style="text-align:left">0x1</td>
<td style="text-align:left">拉流</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">work_mode_push</td>
<td style="text-align:left">0x2</td>
<td style="text-align:left">推流</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">work_mode_capture</td>
<td style="text-align:left">0x4</td>
<td style="text-align:left">自动存截图</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">work_mode_hls</td>
<td style="text-align:left">0x8</td>
<td style="text-align:left">hls</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">work_mode_mp4</td>
<td style="text-align:left">0x10</td>
<td style="text-align:left">mp4</td>
<td style="text-align:left"></td>
</tr>
</tbody>
</table>
<h4 id="toc_102"><a name="toc_102" class="vnote-anchor" href="#"></a>6.1.2.2. 值操作</h4>
<table>
<thead>
<tr>
<th style="text-align:left">枚举值</th>
<th style="text-align:left">值</th>
<th style="text-align:left">描述</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">value_opt_overwrite</td>
<td style="text-align:left">1</td>
<td style="text-align:left">覆盖之前的值</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">value_opt_reserve</td>
<td style="text-align:left">2</td>
<td style="text-align:left">保留之前的值，只替换给定值</td>
<td style="text-align:left"></td>
</tr>
</tbody>
</table>
<h4 id="toc_103"><a name="toc_103" class="vnote-anchor" href="#"></a>6.1.2.3. 协议类型</h4>
<table>
<thead>
<tr>
<th style="text-align:left">枚举值</th>
<th style="text-align:left">值</th>
<th style="text-align:left">描述</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">schema_http</td>
<td style="text-align:left">http</td>
<td style="text-align:left">-</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">schema_https</td>
<td style="text-align:left">https</td>
<td style="text-align:left">-</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">schema_rtsp</td>
<td style="text-align:left">rtsp</td>
<td style="text-align:left">-</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">schema_rtsps</td>
<td style="text-align:left">rtsps</td>
<td style="text-align:left">-</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">schema_rtmp</td>
<td style="text-align:left">rtmp</td>
<td style="text-align:left">-</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">schema_rtmpt</td>
<td style="text-align:left">rtmpt</td>
<td style="text-align:left">-</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">schema_rtmps</td>
<td style="text-align:left">rtmps</td>
<td style="text-align:left">-</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">schema_rtmpe</td>
<td style="text-align:left">rtmpe</td>
<td style="text-align:left">-</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">schema_ hls</td>
<td style="text-align:left">hls</td>
<td style="text-align:left">-</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">schema_flv</td>
<td style="text-align:left">flv</td>
<td style="text-align:left">-</td>
<td style="text-align:left"></td>
</tr>
</tbody>
</table>
<h2 id="toc_104"><a name="toc_104" class="vnote-anchor" href="#"></a>6.2. 序列号编码</h2>
<p>序列号编码规则：</p>
<pre><code class="hljs">        XXXX XXXX XXXXXXXXXX
         │     │       └───────── 对象MAC/编号(12位)
         │     └───────────────── 设备类型(4位)
         └─────────────────────── 厂商代号(4位)                    
</code></pre>
<pre><code class="hljs">┌-----------------------------------------------------------------------------------------------------------┐  
│  STR  │ R  │ M  │ S  │ T  │ T  │ 1  │ 0  │ 0  │ D  │ 8  │ C  │ 4  │ 9  │ 7  │ 3  │ D  │ 4  │ 4  │ 6  │ 6  │
│ ASCII │'R' │'M' │'S' │'T' │'T' │'1' │'0' │'0' │'D' │'8' │'C' │'4' │'9' │'7' │'3' │'D' │'4' │'4' │'6' │'6' │  
│  HEX  │0x52│0x4D│0x53│0x54│0x54│0x31│0x30│0x30│  0xD8   │  0xC4   │  0x97   │  0x3D   │  0x44   │  0x66   │
│  DEC  │ 82 │ 77 │ 83 │ 84 │ 84 │ 49 │ 48 │ 48 │   216   │   196   │   151   │   61    │   68    │   102   │
└-----------------------------------------------------------------------------------------------------------┘

字符串表述："RMST-T100-D8C4973D4466"
十六进制表达："524D5354-54313030-D8C4973D4466" 
</code></pre>
<h2 id="toc_105"><a name="toc_105" class="vnote-anchor" href="#"></a>6.3. 文档日志</h2>
<table>
<thead>
<tr>
<th style="text-align:center">版本</th>
<th style="text-align:center">日期</th>
<th style="text-align:center">操作</th>
<th style="text-align:left">内容</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:center">V1.0.1</td>
<td style="text-align:center">2019-05-12</td>
<td style="text-align:center">周卓</td>
<td style="text-align:left">完善开发文档</td>
</tr>
<tr>
<td style="text-align:center">V1.0.0</td>
<td style="text-align:center">2019-05-01</td>
<td style="text-align:center">周卓</td>
<td style="text-align:left">新增开发手册文档</td>
</tr>
</tbody>
</table>

</body>
</html>
